import Down
import UIKit
import Kingfisher

extension Item {
    var isTaskListItem: Bool {
        // 检查是否包含任务列表标记 [ ] 或 [x]
        if let firstChild = children.first as? Text,
           let literal = firstChild.literal,
           literal.hasPrefix("[ ]") || literal.hasPrefix("[x]") {
            return true
        }
        return false
    }
    
    var taskListItemChecked: Bool {
        // 检查是否是已完成的任务项 [x]
        if let firstChild = children.first as? Text,
           let literal = firstChild.literal,
           literal.hasPrefix("[x]") {
            return true
        }
        return false
    }
}

public class MarkdownASTVisitor: NodeVisitor {
    private let containerWidth: CGFloat
    private let theme: MarkdownTheme
    private let imageBaseURL: URL?
    private let codeBlockStyle: CodeBlockStyle
    private weak var delegate: MarkdownContentViewDelegate?
    private weak var contentView: MarkdownContentView?
    public var customTagHandler: CustomTagHandler
    private let nodeLogger = NodeLogger()
    
    private lazy var paragraphStyle: NSMutableParagraphStyle = {
        let style = NSMutableParagraphStyle()
        style.lineSpacing = theme.paragraph.lineSpacing
        style.paragraphSpacing = theme.paragraph.paragraphSpacing
        style.lineHeightMultiple = theme.paragraph.lineHeightMultiple
        return style
    }()
    
    private lazy var stackView: UIStackView = {
        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 28
        stack.alignment = .fill
        stack.distribution = .fill
        stack.isUserInteractionEnabled = true
        return stack
    }()
    
    @objc func test() {
        print("test========")
    }
    
    @objc func test2() {
        print("test222222")
    }
    
    init(
        containerWidth: CGFloat,
        theme: MarkdownTheme,
        imageBaseURL: URL?,
        codeBlockStyle: CodeBlockStyle = CodeBlockStyle.light,
        delegate: MarkdownContentViewDelegate?,
        contentView: MarkdownContentView?
    ) {
        self.containerWidth = containerWidth
        self.theme = theme
        self.imageBaseURL = imageBaseURL
        self.codeBlockStyle = codeBlockStyle
        self.delegate = delegate
        self.contentView = contentView
        self.customTagHandler = CustomTagHandler()
        self.customTagHandler.delegate = delegate as? CustomTagHandlerDelegate
    }
    
    public func visit(_ document: Document) -> UIView? {
        print("开始解析文档节点")
        nodeLogger.logNodeVisit(document)
        nodeLogger.logRenderingStart(document)
        
        document.children.forEach { node in
            print("解析子节点类型: \(type(of: node))")
            if let view = visitNode(node) {
                stackView.addArrangedSubview(view)
            }
        }
        
        nodeLogger.logRenderingComplete(document, view: stackView)
        return stackView
    }
    
    private func visitNode(_ node: Node) -> UIView? {
        print("访问节点类型: \(type(of: node))")
        nodeLogger.logNodeVisit(node)
        nodeLogger.logRenderingStart(node)
        
        let view: UIView?
        switch node {
        case let heading as Heading:
            print("处理标题节点")
            nodeLogger.logHeadingNode(heading)
            view = visit(heading)
        case let paragraph as Paragraph:
            print("处理段落节点")
            // 检查段落中的图片节点
            if let firstChild = paragraph.children.first as? Image {
                print("段落中发现图片节点")
                return visit(firstChild)
            }
            view = visit(paragraph)
        case let list as List:
            print("处理列表节点")
            view = visit(list)
        case let item as Item:
            print("处理列表项节点")
            view = visit(item)
        case let blockQuote as BlockQuote:
            print("处理引用节点")
            view = visit(blockQuote)
        case let codeBlock as CodeBlock:
            print("处理代码块节点")
            nodeLogger.logCodeBlockNode(codeBlock)
            view = visit(codeBlock)
        case let htmlBlock as HtmlBlock:
            print("处理HTML块节点")
            view = visit(htmlBlock)
        case let text as Text:
            print("处理文本节点")
            nodeLogger.logTextNode(text)
            view = visit(text)
        case let emphasis as Emphasis:
            print("处理强调节点")
            view = visit(emphasis)
        case let strong as Strong:
            print("处理加粗节点")
            view = visit(strong)
        case let link as Link:
            print("处理链接节点")
            nodeLogger.logLinkNode(link)
            view = visit(link)
        case let image as Image:
            print("处理图片节点")
            nodeLogger.logImageNode(image)
            view = visit(image)
        case let softBreak as SoftBreak:
            print("处理软换行节点")
            view = visit(softBreak)
        case let lineBreak as LineBreak:
            print("处理硬换行节点")
            view = visit(lineBreak)
        case let code as Code:
            print("处理行内代码节点")
            view = visit(code)
        case let htmlInline as HtmlInline:
            print("处理行内HTML节点")
            view = visit(htmlInline)
        case let thematicBreak as ThematicBreak:
            print("处理分隔线节点")
            view = visit(thematicBreak)
        default:
            print("未处理的节点类型: \(type(of: node))")
            nodeLogger.logRenderingError(node, error: NSError(domain: "MarkdownASTVisitor", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unhandled node type: \(type(of: node))"]))
            view = nil
        }
        
        nodeLogger.logRenderingComplete(node, view: view)
        return view
    }
    
    private func getNodeText(_ node: Node?) -> NSAttributedString? {
        guard let node = node else { return nil }
        
        let attributedString = NSMutableAttributedString()
        
        switch node {
        case let text as Text:
            print("skipProcessing nextNode get:\(String(describing: (node as? BaseNode)?.isSkipProcessing))" + " -- from : " + "\(text.literal ?? "none")")
            // 检查是否应该跳过处理
            if let baseNode = node as? BaseNode, baseNode.isSkipProcessing {
                return NSAttributedString()
            }
            
            if let literal = text.literal {
                let textAttr = NSAttributedString(
                    string: literal,
                    attributes: [
                        .font: theme.text.font,
                        .foregroundColor: theme.text.textColor
                    ]
                )
                attributedString.append(textAttr)
            }
            
        case let emphasis as Emphasis:
            let emphasisText = NSMutableAttributedString()
            emphasis.children.forEach { child in
                if let childText = getNodeText(child) {
                    emphasisText.append(childText)
                }
            }
            emphasisText.addAttributes([
                .font: theme.text.italicFont,
                .foregroundColor: theme.text.textColor
            ], range: NSRange(location: 0, length: emphasisText.length))
            attributedString.append(emphasisText)
            
        case let strong as Strong:
            let strongText = NSMutableAttributedString()
            strong.children.forEach { child in
                if let childText = getNodeText(child) {
                    strongText.append(childText)
                }
            }
            strongText.addAttributes([
                .font: theme.text.boldFont,
                .foregroundColor: theme.text.textColor
            ], range: NSRange(location: 0, length: strongText.length))
            attributedString.append(strongText)
            
        case let strikethrough as Strikethrough:
            let strikethroughText = NSMutableAttributedString()
            strikethrough.children.forEach { child in
                if let childText = getNodeText(child) {
                    strikethroughText.append(childText)
                }
            }
            strikethroughText.addAttributes([
                .font: theme.text.font,
                .foregroundColor: theme.text.textColor,
                .strikethroughStyle: NSUnderlineStyle.single.rawValue,
                .strikethroughColor: theme.text.textColor
            ], range: NSRange(location: 0, length: strikethroughText.length))
            attributedString.append(strikethroughText)
            
        case let link as Link:
            let linkText = NSMutableAttributedString()
            link.children.forEach { child in
                if let childText = getNodeText(child) {
                    linkText.append(childText)
                }
            }
            
            if let url = link.url {
                var attributes: [NSAttributedString.Key: Any] = [
                    .font: theme.text.font,
                    .paragraphStyle: paragraphStyle,
                    .link: url
                ]
                
                // 根据链接类型设置不同的样式
                if url.hasPrefix("custom://") {
                    attributes[.foregroundColor] = theme.link.customColors.textColor
                    attributes[.backgroundColor] = theme.link.customColors.backgroundColor
                    attributes[.underlineStyle] = NSUnderlineStyle.patternDot.rawValue
                    attributes[.underlineColor] = theme.link.customColors.underlineColor
                } else if url.hasPrefix("#") {
                    attributes[.foregroundColor] = theme.link.externalColors.textColor
                    attributes[.backgroundColor] = theme.link.externalColors.backgroundColor
                    attributes[.underlineStyle] = NSUnderlineStyle.patternDash.rawValue
                    attributes[.underlineColor] = theme.link.externalColors.underlineColor
                } else {
                    attributes[.foregroundColor] = theme.link.defaultColors.textColor
                    attributes[.backgroundColor] = theme.link.defaultColors.backgroundColor
                    attributes[.underlineStyle] = NSUnderlineStyle.single.rawValue
                    attributes[.underlineColor] = theme.link.defaultColors.underlineColor
                }
                
                linkText.addAttributes(attributes, range: NSRange(location: 0, length: linkText.length))
            }
            attributedString.append(linkText)
            
        case let code as Code:
            if let literal = code.literal {
                let codeText = NSAttributedString(
                    string: literal,
                    attributes: [
                        .font: theme.code.inlineFont,
                        .foregroundColor: theme.code.inlineTextColor,
                        .backgroundColor: theme.code.inlineBackgroundColor
                    ]
                )
                attributedString.append(codeText)
            }
        case let htmlInline as HtmlInline:
            if let literal = htmlInline.literal {
                // 解析HTML标签
                if let tagInfo = customTagHandler.parseTag(from: literal) {
                    // 如果是开始标签，获取后续的文本内容
                    if literal.hasSuffix(">") && !literal.hasSuffix("/>") {
                        // 获取下一个节点的文本内容
                        var content = ""
                        var shouldSkipNext = false
                        if let parent = htmlInline.parent,
                           let currentIndex = parent.children.firstIndex(where: { child in
                               // 比较节点类型和内容来确定是否是同一个节点
                               if let childHtml = child as? HtmlInline,
                                  childHtml.literal == htmlInline.literal {
                                   return true
                               }
                               return false
                           }),
                           currentIndex + 1 < parent.children.count,
                           let nextText = getNodeText(parent.children[currentIndex + 1]) {
                            content = nextText.string
                            shouldSkipNext = true
                        }
                        
                        // 创建包含实际内容的新 ParsedTagInfo
                        let updatedTagInfo = ParsedTagInfo(
                            tag: tagInfo.tag,
                            className: tagInfo.className,
                            attributes: tagInfo.attributes,
                            content: content
                        )
                        
                        // 创建自定义视图
                        if let customView = customTagHandler.createView(for: updatedTagInfo) {
                            // 创建自定义附件
                            let attachment = CustomTagAttachment(tagInfo: updatedTagInfo, bounds: CGRect(x: 0, y: -4, width: customView.bounds.width, height: customView.bounds.height))
                            attachment.image = customView.asImage()
                            
                            // 创建带有自定义附件的富文本
                            let attachmentString = NSMutableAttributedString(attachment: attachment)
                            attributedString.append(attachmentString)
                            
                            // 如果使用了下一个节点的内容，设置标记以跳过它
                            if shouldSkipNext,
                               let parent = node.cmarkNode.parent?.wrap(),
                               let currentIndex = parent.children.firstIndex(where: { child in
                                // 比较节点类型和内容来确定是否是同一个节点
                                if let childHtml = child as? HtmlInline,
                                   childHtml.literal == htmlInline.literal {
                                    return true
                                }
                                return false
                            })  {
                                if let nextNode = htmlInline.nextNode as? BaseNode,
                                   let parentNode = htmlInline.parent as? BaseNode {
                                    nextNode.isSkipProcessing = true
                                    (htmlInline.parent as? BaseNode)?.replace(node: nextNode, at: currentIndex + 1)
                                    //(parent.children[currentIndex + 1] as? BaseNode)?.isSkipProcessing = true
                                    if let nextBaseNode = (htmlInline.parent as? BaseNode)?.children[currentIndex + 1] as? BaseNode {
                                        print("skipProcessing nextNode set true:\(String(describing: nextBaseNode.isSkipProcessing)) for \(nextNode.cmarkNode.literal ?? "none")")
                                    }
                                }
                            }
                            
                            return attributedString
                        }
                    }
                    
                    // 如果是自闭合标签，直接创建视图
                    if let customView = customTagHandler.createView(for: tagInfo) {
                        // 创建自定义附件
                        let attachment = CustomTagAttachment(tagInfo: tagInfo, bounds: CGRect(x: 0, y: -4, width: customView.bounds.width, height: customView.bounds.height))
                        attachment.image = customView.asImage()
                        
                        // 创建带有自定义附件的富文本
                        let attachmentString = NSMutableAttributedString(attachment: attachment)
                        attributedString.append(attachmentString)
                        return attributedString
                    }
                }
                
                // 如果不是开始标签或无法创建自定义视图，则作为普通文本处理
                if !literal.hasPrefix("</") { // 忽略结束标签
                    let textAttr = NSAttributedString(
                        string: literal,
                        attributes: [
                            .font: theme.text.font,
                            .foregroundColor: theme.text.textColor
                        ]
                    )
                    attributedString.append(textAttr)
                }
            }
            
            return attributedString
        default:
            node.children.forEach { child in
                if let childText = getNodeText(child) {
                    attributedString.append(childText)
                }
            }
        }
        
        return attributedString
    }
    
    public func visit(_ heading: Heading) -> UIView? {
        let label = UILabel()
        label.numberOfLines = 0
        
        // 创建富文本
        let attributedString = NSMutableAttributedString()
        
        // 获取标题文本
        heading.children.forEach { child in
            if let childText = getNodeText(child) {
                attributedString.append(childText)
            }
        }
        
        // 设置样式
        let style = NSMutableParagraphStyle()
        style.lineSpacing = theme.heading.h1.lineSpacing
        style.paragraphSpacing = theme.heading.h1.paragraphSpacing
        style.lineHeightMultiple = theme.heading.h1.lineHeightMultiple
        
        let range = NSRange(location: 0, length: attributedString.length)
        
        // 根据标题级别设置样式
        switch heading.headingLevel {
        case 1:
            attributedString.addAttributes([
                .font: theme.heading.h1.font,
                .foregroundColor: theme.heading.h1.textColor,
                .paragraphStyle: style
            ], range: range)
        case 2:
            attributedString.addAttributes([
                .font: theme.heading.h2.font,
                .foregroundColor: theme.heading.h2.textColor,
                .paragraphStyle: style
            ], range: range)
        case 3:
            attributedString.addAttributes([
                .font: theme.heading.h3.font,
                .foregroundColor: theme.heading.h3.textColor,
                .paragraphStyle: style
            ], range: range)
        case 4:
            attributedString.addAttributes([
                .font: theme.heading.h4.font,
                .foregroundColor: theme.heading.h4.textColor,
                .paragraphStyle: style
            ], range: range)
        case 5:
            attributedString.addAttributes([
                .font: theme.heading.h5.font,
                .foregroundColor: theme.heading.h5.textColor,
                .paragraphStyle: style
            ], range: range)
        case 6:
            attributedString.addAttributes([
                .font: theme.heading.h6.font,
                .foregroundColor: theme.heading.h6.textColor,
                .paragraphStyle: style
            ], range: range)
        default:
            attributedString.addAttributes([
                .font: theme.heading.h1.font,
                .foregroundColor: theme.heading.h1.textColor,
                .paragraphStyle: style
            ], range: range)
        }
        
        label.attributedText = attributedString
        return label
    }
    
    public func visit(_ paragraph: Paragraph) -> UIView? {
        print("访问段落节点，检查子节点")
        
        // 检查是否只包含一个图片节点
        if paragraph.children.count == 1,
           let image = paragraph.children.first as? Image {
            print("段落中发现单独的图片节点")
            return visit(image)
        }
        
        // 创建 UITextView 替代 UILabel
        let textView = UITextView()
        textView.isScrollEnabled = false
        textView.isEditable = false
        textView.backgroundColor = .clear
        textView.textContainerInset = .zero
        textView.textContainer.lineFragmentPadding = 0
        textView.delegate = contentView as? UITextViewDelegate
        
        // 处理其他段落内容
        let attributedString = NSMutableAttributedString()
        paragraph.children.forEach { child in
            print("处理段落子节点类型: \(type(of: child))")
            if let childText = getNodeText(child) {
                attributedString.append(childText)
            }
        }
        
        // 应用段落样式
        attributedString.addAttributes([
            .paragraphStyle: paragraphStyle,
            .font: theme.text.font,
            .foregroundColor: theme.text.textColor
        ], range: NSRange(location: 0, length: attributedString.length))
        
        textView.attributedText = attributedString
        
        // 根据内容自动调整高度
        let size = textView.sizeThatFits(CGSize(width: containerWidth, height: .greatestFiniteMagnitude))
        textView.frame.size = size
        
        return textView
    }
    
    // 添加自定义 FlexibleStackView 类来支持动换行
    private class FlexibleStackView: UIStackView {
        var flexWrap: Bool = false {
            didSet {
                setNeedsLayout()
            }
        }
        
        override func layoutSubviews() {
            super.layoutSubviews()
            
            if !flexWrap { return }
            
            var currentX: CGFloat = 0
            var currentY: CGFloat = 0
            var rowHeight: CGFloat = 0
            var rowViews: [UIView] = []
            
            // 遍历所有子视图进行布局
            for view in arrangedSubviews {
                let width = view.intrinsicContentSize.width
                let height = view.intrinsicContentSize.height
                
                // 检查是否需要换行
                if currentX + width > bounds.width && currentX > 0 {
                    // 布局当前行
                    layoutRow(views: rowViews, y: currentY, height: rowHeight)
                    
                    // 重置行数据
                    currentX = 0
                    currentY += rowHeight + spacing
                    rowHeight = 0
                    rowViews.removeAll()
                }
                
                // 添加视图到当前行
                rowViews.append(view)
                currentX += width + spacing
                rowHeight = max(rowHeight, height)
            }
            
            // 布局最后一行
            if !rowViews.isEmpty {
                layoutRow(views: rowViews, y: currentY, height: rowHeight)
            }
        }
        
        private func layoutRow(views: [UIView], y: CGFloat, height: CGFloat) {
            var x: CGFloat = 0
            
            for view in views {
                let width = view.intrinsicContentSize.width
                view.frame = CGRect(x: x, y: y, width: width, height: height)
                x += width + spacing
            }
        }
        
        override var intrinsicContentSize: CGSize {
            if !flexWrap { return super.intrinsicContentSize }
            
            var maxWidth: CGFloat = 0
            var totalHeight: CGFloat = 0
            var currentX: CGFloat = 0
            var rowHeight: CGFloat = 0
            var currentRowWidth: CGFloat = 0
            
            // 遍历所有子视图计算尺寸
            for view in arrangedSubviews {
                let size = view.intrinsicContentSize
                
                // 检查是否需要换行
                if currentX + size.width > bounds.width && currentX > 0 {
                    // 更新最大宽度
                    maxWidth = max(maxWidth, currentRowWidth)
                    
                    // 添加当前行高度
                    totalHeight += rowHeight + spacing
                    
                    // 重置行数据
                    currentX = 0
                    rowHeight = 0
                    currentRowWidth = 0
                }
                
                // 更新当前行数据
                currentX += size.width + spacing
                rowHeight = max(rowHeight, size.height)
                currentRowWidth = currentX - spacing
            }
            
            // 处理最后一行
            if rowHeight > 0 {
                maxWidth = max(maxWidth, currentRowWidth)
                totalHeight += rowHeight
            }
            
            // 如果没有内容，返回零尺寸
            if totalHeight == 0 {
                return .zero
            }
            
            // 返回计算后的尺寸
            return CGSize(
                width: maxWidth,
                height: totalHeight
            )
        }
    }
    
    public func visit(_ text: Text) -> UIView? {
        let label = UILabel()
        label.numberOfLines = 0
        label.text = text.literal
        label.font = .systemFont(ofSize: 16)
        label.textColor = theme.text.textColor
        return label
    }
    
    public func visit(_ link: Link) -> UIView? {
        let label = UILabel()
        label.numberOfLines = 0
        
        // 获取链接文本
        let text = link.children.compactMap { getNodeText($0)?.string ?? "" }.joined()
        
        // 创建富文本
        let attributedString = NSMutableAttributedString(
            string: text,
            attributes: [
                .font: theme.text.font,
                .foregroundColor: theme.link.defaultColors.textColor,
                .underlineStyle: NSUnderlineStyle.single.rawValue,
                .underlineColor: theme.link.defaultColors.underlineColor,
                // 添加自定义属性来存储 URL
                .link: link.url ?? ""
            ]
        )
        
        label.attributedText = attributedString
        
        // 启用用户交互
        label.isUserInteractionEnabled = true
        
        // 添加点击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleLabelTap(_:)))
        label.isUserInteractionEnabled = true
        label.addGestureRecognizer(tapGesture)
        
        // 优化布局
        label.setContentHuggingPriority(.required, for: .horizontal)
        label.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        return label
    }
    
    @objc private func handleLabelTap(_ gesture: UITapGestureRecognizer) {
        guard let label = gesture.view as? UILabel,
              let attributedText = label.attributedText else { return }
        
        let point = gesture.location(in: label)
        
        // 获取点击位置的字符索引
        let textContainer = NSTextContainer(size: label.bounds.size)
        let layoutManager = NSLayoutManager()
        let textStorage = NSTextStorage(attributedString: attributedText)
        
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)
        
        textContainer.lineFragmentPadding = 0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        
        let index = layoutManager.characterIndex(
            for: point,
            in: textContainer,
            fractionOfDistanceBetweenInsertionPoints: nil
        )
        
        // 检查点击位置是否有链接属性
        if index < attributedText.length {
            let range = NSRange(location: 0, length: attributedText.length)
            attributedText.enumerateAttribute(.link, in: range, options: []) { value, range, _ in
                if range.contains(index),
                   let urlString = value as? String,
                   let url = URL(string: urlString) {
                    
                    // 直接使用 delegate 处理链接点击
                    if let delegate = delegate,
                       delegate.markdownContentView(delegate as! MarkdownContentView, shouldHandleLink: url) {
                        UIApplication.shared.open(url) { success in
                            if success {
                                delegate.markdownContentView(delegate as! MarkdownContentView, didHandleLink: url)
                            } else {
                                let error = NSError(
                                    domain: "MarkdownUIKit",
                                    code: -1,
                                    userInfo: [NSLocalizedDescriptionKey: "Failed to open URL"]
                                )
                                delegate.markdownContentView(delegate as! MarkdownContentView, failedToHandleLink: url, error: error)
                            }
                        }
                    }
                }
            }
        }
    }
    
    // 添加辅助方法处理链接点击
    private func handleLinkTap(_ url: URL) {
        if url.scheme == "image" {
            // 处理图片链接
            delegate?.markdownContentView(MarkdownContentView(), didTapImage: url)
        } else {
            // 处理普通链接
            if delegate?.markdownContentView(MarkdownContentView(), shouldHandleLink: url) ?? true {
                // 尝试打开链接
                if UIApplication.shared.canOpenURL(url) {
                    UIApplication.shared.open(url) { success in
                        if success {
                            self.delegate?.markdownContentView(MarkdownContentView(), didHandleLink: url)
                        } else {
                            let error = NSError(
                                domain: "MarkdownContentView",
                                code: -1,
                                userInfo: [NSLocalizedDescriptionKey: "Failed to open URL"]
                            )
                            self.delegate?.markdownContentView(
                                MarkdownContentView(),
                                failedToHandleLink: url,
                                error: error
                            )
                        }
                    }
                } else {
                    let error = NSError(
                        domain: "MarkdownContentView",
                        code: -2,
                        userInfo: [NSLocalizedDescriptionKey: "Cannot open URL"]
                    )
                    delegate?.markdownContentView(
                        MarkdownContentView(),
                        failedToHandleLink: url,
                        error: error
                    )
                }
            }
        }
    }
    
    public func visit(_ image: Image) -> UIView? {
        nodeLogger.logImageNode(image)
        nodeLogger.logRenderingStart(image)
        
        let delegateAdapter = DelegateAdapter(delegate: delegate, contentView: contentView)
        let renderer = ImageRenderer(
            theme: theme,
            containerWidth: containerWidth,
            imageBaseURL: imageBaseURL,
            delegate: delegateAdapter
        )
        
        let view = renderer.renderImage(from: image.url, title: image.title)
        nodeLogger.logRenderingComplete(image, view: view)
        return view
    }
    
    // 存储图片 URL 的数组
    private var imageURLs: [URL] = []
    
    private func storeImageURL(_ url: URL) -> Int {
        imageURLs.append(url)
        return imageURLs.count - 1
    }
    
    @objc private func handleImageTap(_ gesture: UITapGestureRecognizer) {
        guard let view = gesture.view,
              view.tag < imageURLs.count else { return }
        
        let url = imageURLs[view.tag]
        delegate?.markdownContentView(MarkdownContentView(), didTapImage: url)
    }
    
    public func visit(_ codeBlock: CodeBlock) -> UIView? {
        print("处理代码块节点")
        nodeLogger.logCodeBlockNode(codeBlock)
        
        // 使用 MarkdownContentView 的配置创建代码块
        if let markdownContentView = contentView {
            let codeBlockView = markdownContentView.createCodeBlockView(
                language: codeBlock.fenceInfo,
                code: codeBlock.literal ?? ""
            )
            
            // 设置代码块样式
            codeBlockView.style = codeBlockStyle
            
            // 确保显示顶部视图
            codeBlockView.showHeader = true
            codeBlockView.showLanguageLabel = true
            codeBlockView.showCopyButton = true
            
            // 设置语言显示
            if let language = codeBlock.fenceInfo {
                codeBlockView.languageDisplayName = language.uppercased()
            }
            
            // 应用样式
            codeBlockView.updateTheme()
            
            return codeBlockView
        }
        
        // 如果没有 MarkdownContentView，使用默认配置
        let container = UIView()
        container.backgroundColor = codeBlockStyle.backgroundColor
        container.layer.cornerRadius = theme.code.cornerRadius
        container.layer.masksToBounds = true
        
        let label = UILabel()
        label.numberOfLines = 0
        
        // 处理代码块内容
        if let literal = codeBlock.literal {
            // 创建语法高亮器
            let highlighter = SyntaxHighlighter(theme: SyntaxTheme.xcode)
            
            // 应用语法高亮
            label.attributedText = highlighter.highlight(literal, language: codeBlock.fenceInfo ?? "")
        }
        
        container.addSubview(label)
        label.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(theme.code.codeBlockPadding)
        }
        
        return container
    }
    
    public func visit(_ htmlBlock: HtmlBlock) -> UIView? {
        guard let literal = htmlBlock.literal else { return nil }
        
        // 解析 HTML 标签
        let parser = HTMLTagParser()
        guard let tagInfo = parser.parse(literal) else { return nil }
        
        // 尝试使用自定义标签处理器创建视图
        if let customView = customTagHandler.createView(for: ParsedTagInfo(
            tag: tagInfo.type.description,
            className: tagInfo.attributes["class"],
            attributes: tagInfo.attributes,
            content: tagInfo.content
        )) {
            return customView
        }
        
        // 如果没有自定义处理，创建默认视图
        return createDefaultHTMLView(for: tagInfo)
    }
    
    public func visit(_ htmlInline: HtmlInline) -> UIView? {
        guard let literal = htmlInline.literal else { return nil }
        
        // 解析 HTML 标签
        let parser = HTMLTagParser()
        guard let tagInfo = parser.parse(literal) else { return nil }
        
        // 尝试使用自定义标签处理器创建视图
        if let customView = customTagHandler.createView(for: ParsedTagInfo(
            tag: tagInfo.type.description,
            className: tagInfo.attributes["class"],
            attributes: tagInfo.attributes,
            content: tagInfo.content
        )) {
            return customView
        }
        
        // 如果没有自定义处理，创建默认视图
        return createDefaultHTMLView(for: tagInfo)
    }
    
    private func createDefaultHTMLView(for tagInfo: HTMLTagParser.TagInfo) -> UIView? {
        // 创建默认的标签视图
        let label = PaddingLabel()
        label.numberOfLines = 0
        label.text = tagInfo.content
        label.font = .systemFont(ofSize: 16)
        
        // 处理链接
        if tagInfo.type == .a {
            if let href = tagInfo.attributes["href"],
               let url = URL(string: href) {
                // 创建富文本
                let attributedString = NSMutableAttributedString(
                    string: tagInfo.content,
                    attributes: [
                        .font: UIFont.systemFont(ofSize: 16),
                        .foregroundColor: theme.link.customColors.textColor,
                        .underlineStyle: NSUnderlineStyle.single.rawValue,
                        .underlineColor: theme.link.customColors.underlineColor,
                        .link: url.absoluteString
                    ]
                )
                label.attributedText = attributedString
                
                // 启用用户交互
                label.isUserInteractionEnabled = true
                let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleLabelTap(_:)))
                label.addGestureRecognizer(tapGesture)
            }
        }
        
        return label
    }
    
    public func visit(_ blockQuote: BlockQuote) -> UIView? {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = theme.list.itemSpacing
        
        let container = UIView()
        container.backgroundColor = theme.quote.backgroundColor
        container.layer.cornerRadius = 4
        
        // 创建左侧边框
        let borderView = UIView()
        borderView.backgroundColor = theme.quote.borderColor
        container.addSubview(borderView)
        
        // 创建引用内容
        let contentStack = UIStackView()
        contentStack.axis = .vertical
        contentStack.spacing = theme.list.itemSpacing
        
        blockQuote.children.forEach { node in
            if let view = visitNode(node) {
                contentStack.addArrangedSubview(view)
            }
        }
        
        container.addSubview(contentStack)
        
        // 设置约束
        borderView.snp.makeConstraints { make in
            make.left.top.bottom.equalToSuperview()
            make.width.equalTo(4)
        }
        
        contentStack.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(8)
            make.bottom.equalToSuperview().offset(-8)
            make.left.equalTo(borderView.snp.right).offset(12)
            make.right.equalToSuperview().offset(-12)
        }
        
        stackView.addArrangedSubview(container)
        return stackView
    }
    
    public func visit(_ list: List) -> UIView? {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = theme.list.itemSpacing
        stackView.alignment = .fill
        stackView.distribution = .fill
        
        // 遍历列表项
        list.children.enumerated().forEach { index, item in
            if let itemNode = item as? Item,
               let itemView = visit(itemNode) {
                let container = UIStackView()
                container.axis = .horizontal
                container.spacing = 8
                container.alignment = .top
                container.distribution = .fill
                
                // 添加列表标记
                let bulletLabel = UILabel()
                bulletLabel.font = theme.list.bulletFont
                bulletLabel.textColor = theme.list.bulletColor
                bulletLabel.textAlignment = .right
                bulletLabel.setContentHuggingPriority(.required, for: .horizontal)
                bulletLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
                
                // 根据列表类型设置标记
                switch list.listType {
                case .bullet:
                    // 检查是否是任务列表项
                    if itemNode.isTaskListItem {
                        let checkbox = UIButton(type: .custom)
                        let isChecked = delegate?.markdownContentView(contentView ?? MarkdownContentView(), isTaskListItemChecked: index) ?? false
                        checkbox.setImage(UIImage(systemName: isChecked ? "checkmark.square.fill" : "square"), for: .normal)
                        checkbox.tintColor = theme.list.taskListCheckboxTintColor
                        checkbox.snp.makeConstraints { make in
                            make.width.height.equalTo(theme.list.taskListCheckboxSize)
                        }
                        
                        // 添加点击事件
                        checkbox.tag = index
                        checkbox.addTarget(self, action: #selector(handleTaskListCheckboxTap(_:)), for: .touchUpInside)
                        
                        container.addArrangedSubview(checkbox)
                    } else {
                        bulletLabel.text = "•"
                        bulletLabel.snp.makeConstraints { make in
                            make.width.equalTo(20)
                        }
                        container.addArrangedSubview(bulletLabel)
                    }
                case .ordered:
                    bulletLabel.text = "\(index + 1)."
                    bulletLabel.snp.makeConstraints { make in
                        make.width.equalTo(25)
                    }
                    container.addArrangedSubview(bulletLabel)
                }
                
                // 添加内容
                container.addArrangedSubview(itemView)
                
                // 添加到主容器
                stackView.addArrangedSubview(container)
            }
        }
        
        return stackView
    }
    
    @objc private func handleTaskListCheckboxTap(_ sender: UIButton) {
        // 通知代理任务列表项状态改变
        delegate?.markdownContentView(contentView ?? MarkdownContentView(), didToggleTaskListItem: sender.tag)
    }
    
    public func visit(_ emphasis: Emphasis) -> UIView? {
        let label = UILabel()
        label.numberOfLines = 0
        
        // 创建富文本
        let attributedString = NSMutableAttributedString()
        
        // 遍历子节点并添加文本
        for child in emphasis.children {
            if let childText = getNodeText(child) {
                attributedString.append(childText)
            }
        }
        
        // 检查是否有内容需要设置样式
        if attributedString.length > 0 {
            // 应用斜体样式
            attributedString.addAttributes([
                .font: theme.text.italicFont,
                .foregroundColor: theme.text.textColor
            ], range: NSRange(location: 0, length: attributedString.length))
            
            label.attributedText = attributedString
            
            // 设置内容优先级
            label.setContentHuggingPriority(.required, for: .horizontal)
            label.setContentCompressionResistancePriority(.required, for: .horizontal)
        }
        
        return label
    }
    
    public func visit(_ strong: Strong) -> UIView? {
        let label = UILabel()
        label.numberOfLines = 0
        
        let attributedString = NSMutableAttributedString()
        
        for child in strong.children {
            if let childText = getNodeText(child) {
                attributedString.append(childText)
            }
        }
        
        // 应用粗体样式
        let range = NSRange(location: 0, length: attributedString.length)
        attributedString.addAttributes([
            .font: theme.text.boldFont,
            .foregroundColor: theme.text.textColor
        ], range: range)
        
        label.attributedText = attributedString
        return label
    }
    
    public func visit(_ item: Item) -> UIView? {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = theme.list.itemSpacing
        stackView.alignment = .fill
        stackView.distribution = .fill
        
        // 遍历子节点
        var isFirstChild = true
        for node in item.children {
            if isFirstChild && item.isTaskListItem {
                if let text = node as? Text,
                   let literal = text.literal,
                   (literal.hasPrefix("[ ]") || literal.hasPrefix("[x]")) {
                    // 直接创建标签显示清理后的文本
                    let cleanedLiteral = String(literal.dropFirst(3)).trimmingCharacters(in: .whitespaces)
                    let label = UILabel()
                    label.numberOfLines = 0
                    label.font = theme.text.font
                    
                    // 根据任务项状态设置样式
                    let isChecked = literal.hasPrefix("[x]")
                    if isChecked {
                        label.textColor = theme.list.taskListCompletedTextColor
                        if theme.list.taskListStrikethrough {
                            let attributedText = NSAttributedString(
                                string: cleanedLiteral,
                                attributes: [
                                    .strikethroughStyle: NSUnderlineStyle.single.rawValue,
                                    .strikethroughColor: theme.list.taskListCompletedTextColor
                                ]
                            )
                            label.attributedText = attributedText
                        } else {
                            label.text = cleanedLiteral
                        }
                    } else {
                        label.textColor = theme.list.taskListTextColor
                        label.text = cleanedLiteral
                    }
                    
                    stackView.addArrangedSubview(label)
                } else {
                    if let view = visitNode(node) {
                        stackView.addArrangedSubview(view)
                    }
                }
            } else {
                if let view = visitNode(node) {
                    stackView.addArrangedSubview(view)
                }
            }
            isFirstChild = false
        }
        
        return stackView
    }
    
    public func visit(_ softBreak: SoftBreak) -> UIView? {
        let label = UILabel()
        label.text = "\n"
        label.font = .systemFont(ofSize: 16)
        return label
    }
    
    public func visit(_ lineBreak: LineBreak) -> UIView? {
        let label = UILabel()
        label.text = "\n"
        label.font = .systemFont(ofSize: 16)
        return label
    }
    
    public func visit(_ thematicBreak: ThematicBreak) -> UIView? {
        let separator = UIView()
        separator.backgroundColor = .systemGray4
        
        let container = UIView()
        container.addSubview(separator)
        
        separator.snp.makeConstraints { make in
            make.height.equalTo(1)
            make.left.right.equalToSuperview()
            make.centerY.equalToSuperview()
        }
        
        container.snp.makeConstraints { make in
            make.height.equalTo(20)
        }
        
        return container
    }
    
    private func createCustomTagView(_ tagInfo: HTMLTagParser.TagInfo) -> UIView? {
        // 首先尝试使用注册的自定义标签处理器
        if let customView = customTagHandler.createView(for: ParsedTagInfo(
            tag: tagInfo.type.description,
            className: tagInfo.attributes["class"],
            attributes: tagInfo.attributes,
            content: tagInfo.content
        )) {
            return customView
        }
        
        // 创建标签视图
        let label = PaddingLabel()  // 使用 PaddingLabel 替代 UILabel
        label.numberOfLines = 0
        label.text = tagInfo.content
        label.font = .systemFont(ofSize: 16)
        
        // 基本样式设置
        label.setContentHuggingPriority(.required, for: .horizontal)
        label.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        // 处理链接
        if tagInfo.type == .a {
            if let href = tagInfo.attributes["href"],
               let url = URL(string: href) {
                // 创建富文本
                let attributedString = NSMutableAttributedString(
                    string: tagInfo.content,
                    attributes: [
                        .font: UIFont.systemFont(ofSize: 16),
                        .foregroundColor: theme.link.defaultColors.textColor,
                        .underlineStyle: NSUnderlineStyle.single.rawValue,
                        .underlineColor: theme.link.defaultColors.underlineColor,
                        .link: url.absoluteString
                    ]
                )
                label.attributedText = attributedString
                
                // 启用用户交互
                label.isUserInteractionEnabled = true
                let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleLabelTap(_:)))
                label.addGestureRecognizer(tapGesture)
            }
        }
        
        // 处理样式属性
        if let style = tagInfo.attributes["style"] {
              applyStyle(style, to: label)
        }
        
        // 处理特定的 class
        if let className = tagInfo.attributes["class"] {
            switch className {
            case "ncTag":
                // 创建带背景的富文本
                let attributedString = NSMutableAttributedString(
                    string: tagInfo.content,
                    attributes: [
                        .font: UIFont.systemFont(ofSize: 16),
                        .foregroundColor: UIColor.systemBlue
                    ]
                )
                label.attributedText = attributedString
                
                // 设置背景和圆角
                label.backgroundColor = .systemBlue.withAlphaComponent(0.1)
                label.layer.cornerRadius = 4
                label.layer.masksToBounds = true
                
                // 添加内边距
                label.padding = UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4)
                
            case "userTag":
                // 创建带背景的富文本
                let attributedString = NSMutableAttributedString(
                    string: tagInfo.content,
                    attributes: [
                        .font: UIFont.systemFont(ofSize: 16),
                        .foregroundColor: UIColor.systemGreen
                    ]
                )
                label.attributedText = attributedString
                
                // 设置背景和圆角
                label.backgroundColor = UIColor.green
                label.layer.cornerRadius = 4
                label.layer.masksToBounds = true
                
                // 添加内边距
                label.padding = UIEdgeInsets(top: 2, left: 4, bottom: 2, right: 4)
                
            default:
                break
            }
        }
        
        return label
    }
    
    // 其他节点类型的访问方法...
    
    private func getPlainText(_ node: Node?) -> String? {
        return getNodeText(node)?.string
    }
    
    @objc private func handleLinkTap(_ gesture: UITapGestureRecognizer) {
        guard let label = gesture.view as? UILabel,
              let attributedText = label.attributedText else { return }
        
        let point = gesture.location(in: label)
        
        // 创建文本布局管理器
        let textStorage = NSTextStorage(attributedString: attributedText)
        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: label.bounds.size)
        
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)
        
        textContainer.lineFragmentPadding = 0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        
        // 获取点击位置对应的字符索引
        let index = layoutManager.characterIndex(
            for: point,
            in: textContainer,
            fractionOfDistanceBetweenInsertionPoints: nil
        )
        
        // 检查点击位置是否在文本范围内
        guard index < attributedText.length else { return }
        
        // 查找链接属性
        let range = NSRange(location: 0, length: attributedText.length)
        attributedText.enumerateAttribute(.link, in: range, options: []) { value, range, stop in
            if range.contains(index),
               let urlString = value as? String,
               let url = URL(string: urlString) {
                stop.pointee = true
                
                // 通过代理处理链接点击
                if let delegate = delegate as? MarkdownContentView {
                    if delegate.markdownContentView(delegate, shouldHandleLink: url) {
                        UIApplication.shared.open(url) { success in
                            if success {
                                delegate.markdownContentView(delegate, didHandleLink: url)
                            } else {
                                let error = NSError(
                                    domain: "MarkdownUIKit",
                                    code: -1,
                                    userInfo: [NSLocalizedDescriptionKey: "Failed to open URL"]
                                )
                                delegate.markdownContentView(delegate, failedToHandleLink: url, error: error)
                            }
                        }
                    }
                }
            }
        }
    }
    
    private func applyStyle(_ styleString: String, to label: UILabel) {
        // 分割样式属性
        let styles = styleString.components(separatedBy: ";")
        
        for style in styles {
            let parts = style.components(separatedBy: ":")
            guard parts.count == 2 else { continue }
            
            let property = parts[0].trimmingCharacters(in: .whitespaces)
            let value = parts[1].trimmingCharacters(in: .whitespaces)
            
            switch property {
            case "color":
                // 处理颜色
                if value.hasPrefix("#") {
                    label.textColor = UIColor.fromHex(value)
                } else {
                    // 处理命名颜色
                    switch value {
                    case "red": label.textColor = .systemRed
                    case "blue": label.textColor = .systemBlue
                    case "green": label.textColor = .systemGreen
                    case "yellow": label.textColor = .systemYellow
                    case "gray": label.textColor = .systemGray
                    case "white": label.textColor = .white
                    case "black": label.textColor = .black
                    default: break
                    }
                }
                
            case "background-color":
                // 处理背景色
                if value.hasPrefix("#") {
                    label.backgroundColor = UIColor.fromHex(value)
                } else {
                    // 处理命名颜色
                    switch value {
                    case "red": label.backgroundColor = .systemRed
                    case "blue": label.backgroundColor = .systemBlue
                    case "green": label.backgroundColor = .systemGreen
                    case "yellow": label.backgroundColor = .systemYellow
                    case "gray": label.backgroundColor = .systemGray
                    case "white": label.backgroundColor = .white
                    case "black": label.backgroundColor = .black
                    default: break
                    }
                }
                
            case "font-size":
                // 处理字体大小
                if let size = value.replacingOccurrences(of: "px", with: "").toFloat() {
                    label.font = .systemFont(ofSize: CGFloat(size))
                }
                
            case "font-weight":
                // 处理字体粗细
                switch value {
                case "bold":
                    label.font = .boldSystemFont(ofSize: label.font.pointSize)
                case "normal":
                    label.font = .systemFont(ofSize: label.font.pointSize)
                default:
                    if let weight = value.toFloat(),
                       let systemWeight = getFontWeight(from: weight) {
                        label.font = .systemFont(ofSize: label.font.pointSize, weight: systemWeight)
                    }
                }
                
            case "text-align":
                // 处理文本对齐
                switch value {
                case "left": label.textAlignment = .left
                case "center": label.textAlignment = .center
                case "right": label.textAlignment = .right
                case "justify": label.textAlignment = .justified
                default: break
                }
                
            case "padding":
                // 处理内边距（如果是 PaddingLabel）
                if let paddingLabel = label as? PaddingLabel {
                    let values = value.components(separatedBy: " ")
                    switch values.count {
                    case 1:
                        // 所有边相同
                        if let padding = values[0].replacingOccurrences(of: "px", with: "").toFloat() {
                            paddingLabel.padding = UIEdgeInsets(top: CGFloat(padding),
                                                              left: CGFloat(padding),
                                                              bottom: CGFloat(padding),
                                                              right: CGFloat(padding))
                        }
                    case 2:
                        // 上下、左右
                        let vertical = values[0].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        let horizontal = values[1].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        paddingLabel.padding = UIEdgeInsets(top: CGFloat(vertical),
                                                          left: CGFloat(horizontal),
                                                          bottom: CGFloat(vertical),
                                                          right: CGFloat(horizontal))
                    case 4:
                        // 上、右、下、左
                        let top = values[0].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        let right = values[1].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        let bottom = values[2].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        let left = values[3].replacingOccurrences(of: "px", with: "").toFloat() ?? 0
                        paddingLabel.padding = UIEdgeInsets(top: CGFloat(top),
                                                          left: CGFloat(left),
                                                          bottom: CGFloat(bottom),
                                                          right: CGFloat(right))
                    default:
                        break
                    }
                }
                
            default:
                break
            }
        }
    }
    
    private func getFontWeight(from value: Float) -> UIFont.Weight? {
        switch value {
        case 100: return .thin
        case 200: return .ultraLight
        case 300: return .light
        case 400: return .regular
        case 500: return .medium
        case 600: return .semibold
        case 700: return .bold
        case 800: return .heavy
        case 900: return .black
        default: return nil
        }
    }
    
    // MARK: - Code Highlighting

    private func highlightCode(_ code: String, language: String?) -> NSAttributedString {
        let attributedString = NSMutableAttributedString(string: code)
        let range = NSRange(location: 0, length: code.count)
        
        // 设置基本属性
        attributedString.addAttributes([
            .font: codeBlockStyle.font,
            .foregroundColor: codeBlockStyle.textColor
        ], range: range)
        
        // 根据语言应用语法高亮
        if let language = language?.lowercased() {
            switch language {
            case "swift":
                highlightSwiftSyntax(in: attributedString)
            case "python":
                highlightPythonSyntax(in: attributedString)
            case "javascript", "js":
                highlightJavaScriptSyntax(in: attributedString)
            case "html":
                highlightHTMLSyntax(in: attributedString)
            case "css":
                highlightCSSSyntax(in: attributedString)
            case "json":
                highlightJSONSyntax(in: attributedString)
            default:
                highlightGenericSyntax(in: attributedString)
            }
        }
        
        return attributedString
    }
    
    private func highlightSwiftSyntax(in code: NSMutableAttributedString) {
        // 关键字
        let keywords = "\\b(class|struct|enum|protocol|extension|func|var|let|if|else|guard|return|true|false|nil|self|super|init|deinit|throws|throw|try|catch|as|is|switch|case|default|break|continue|where|while|for|in|repeat|do|import)\\b"
        highlightPattern(keywords, in: code, color: .systemPink)
        
        // 类型
        let types = "\\b(String|Int|Double|Float|Bool|Character|Array|Dictionary|Set|Optional|Result|Error|Void|Any|AnyObject)\\b"
        highlightPattern(types, in: code, color: .systemBlue)
        
        // 字符串
        let strings = "\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"|'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'"
        highlightPattern(strings, in: code, color: .systemGreen)
        
        // 注释
        let comments = "//.*$|/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
        
        // 数字
        let numbers = "\\b\\d+\\.?\\d*\\b"
        highlightPattern(numbers, in: code, color: .systemOrange)
    }
    
    private func highlightPythonSyntax(in code: NSMutableAttributedString) {
        // 关键字
        let keywords = "\\b(def|class|if|else|elif|while|for|in|try|except|finally|with|as|assert|break|continue|return|yield|import|from|pass|raise|True|False|None)\\b"
        highlightPattern(keywords, in: code, color: .systemPink)
        
        // 内置类型
        let types = "\\b(str|int|float|bool|list|dict|set|tuple|object)\\b"
        highlightPattern(types, in: code, color: .systemBlue)
        
        // 字符串
        let strings = "(['\"])(?:(?!\\1|\\\\).|\\\\.)*\\1"
        highlightPattern(strings, in: code, color: .systemGreen)
        
        // 注释
        let comments = "#.*$"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
        
        // 数字
        let numbers = "\\b\\d+\\.?\\d*\\b"
        highlightPattern(numbers, in: code, color: .systemOrange)
    }
    
    private func highlightJavaScriptSyntax(in code: NSMutableAttributedString) {
        // 关键字
        let keywords = "\\b(function|var|let|const|if|else|for|while|do|switch|case|break|continue|return|try|catch|finally|throw|class|extends|new|this|super|import|export|default|null|undefined|true|false)\\b"
        highlightPattern(keywords, in: code, color: .systemPink)
        
        // 内置对象和类型
        let types = "\\b(Array|Object|String|Number|Boolean|Function|Promise|Map|Set|Symbol|Date|RegExp|Error)\\b"
        highlightPattern(types, in: code, color: .systemBlue)
        
        // 字符串
        let strings = "(['\"`])(?:(?!\\1|\\\\).|\\\\.)*\\1"
        highlightPattern(strings, in: code, color: .systemGreen)
        
        // 注释
        let comments = "//.*$|/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
        
        // 数字
        let numbers = "\\b\\d+\\.?\\d*\\b"
        highlightPattern(numbers, in: code, color: .systemOrange)
    }
    
    private func highlightHTMLSyntax(in code: NSMutableAttributedString) {
        // 标签
        let tags = "</?[a-zA-Z][^>]*>"
        highlightPattern(tags, in: code, color: .systemBlue)
        
        // 属性
        let attributes = "\\b[a-zA-Z-]+="
        highlightPattern(attributes, in: code, color: .systemPink)
        
        // 属性值
        let values = "\"[^\"]*\""
        highlightPattern(values, in: code, color: .systemGreen)
        
        // 注释
        let comments = "<!--[^>]*-->"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
    }
    
    private func highlightCSSSyntax(in code: NSMutableAttributedString) {
        // 选择器
        let selectors = "[.#]?[a-zA-Z][-_a-zA-Z0-9]*(?=[\\s{,])"
        highlightPattern(selectors, in: code, color: .systemBlue)
        
        // 属性
        let properties = "[-a-zA-Z]+(?=\\s*:)"
        highlightPattern(properties, in: code, color: .systemPink)
        
        // 值
        let values = ":\\s*[^;\\n}]+;"
        highlightPattern(values, in: code, color: .systemGreen)
        
        // 注释
        let comments = "/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
    }
    
    private func highlightJSONSyntax(in code: NSMutableAttributedString) {
        // 键
        let keys = "\"[^\"]+\"(?=\\s*:)"
        highlightPattern(keys, in: code, color: .systemPink)
        
        // 字符串值
        let strings = "(?<=:\\s*)\"[^\"]*\""
        highlightPattern(strings, in: code, color: .systemGreen)
        
        // 数字
        let numbers = "(?<=:\\s*)\\-?\\d+\\.?\\d*([eE][+-]?\\d+)?"
        highlightPattern(numbers, in: code, color: .systemOrange)
        
        // 布尔值和null
        let keywords = "(?<=:\\s*)(true|false|null)\\b"
        highlightPattern(keywords, in: code, color: .systemPurple)
    }
    
    private func highlightGenericSyntax(in code: NSMutableAttributedString) {
        // 字符串
        let strings = "\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"|'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'"
        highlightPattern(strings, in: code, color: .systemGreen)
        
        // 注释
        let comments = "//.*$|/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/"
        highlightPattern(comments, in: code, color: .systemGray, isItalic: true)
        
        // 数字
        let numbers = "\\b\\d+\\.?\\d*\\b"
        highlightPattern(numbers, in: code, color: .systemOrange)
    }
    
    private func highlightPattern(_ pattern: String, in code: NSMutableAttributedString, color: UIColor, isItalic: Bool = false) {
        guard let regex = try? NSRegularExpression(pattern: pattern, options: [.anchorsMatchLines]) else { return }
        let range = NSRange(location: 0, length: code.length)
        let matches = regex.matches(in: code.string, options: [], range: range)
        
        for match in matches {
            var attributes: [NSAttributedString.Key: Any] = [.foregroundColor: color]
            if isItalic {
                attributes[.font] = codeBlockStyle.font.with(.traitItalic)
            }
            code.addAttributes(attributes, range: match.range)
        }
    }
    
    private func createCodeBlock(language: String?, code: String) -> UIView {
        // 使用 MarkdownContentView 的配置创建代码块
        if let markdownContentView = contentView as? MarkdownContentView {
            let codeBlockView = markdownContentView.createCodeBlockView(language: language, code: code)
            codeBlockView.style = codeBlockStyle
            return codeBlockView
        } else {
            // 如果没有 MarkdownContentView，使用默认配置
            let codeBlockView = CodeBlockView(language: language, code: code)
            codeBlockView.style = codeBlockStyle
            return codeBlockView
        }
    }
    
    private func visitCodeBlock(_ node: CodeBlock) -> UIView? {
        let language = node.fenceInfo
        let code = node.literal ?? ""
        return createCodeBlock(language: language, code: code)
    }
} 
